We now know how to create many plot types using ggplot2, but often you want to customize your plots. Today, we’ll discuss common tools for customizing our plots.
To begin, make sure that you have the tidyverse loaded.
library(tidyverse)
Also, let’s start with our plot from the exercise
scorecard <- read_csv("https://github.com/cmsc205/data/raw/master/ScorecardSmallNarrow.csv")
p <-
scorecard %>%
ggplot(aes(x=ADM_RATE, y=net_cost)) +
geom_point(alpha = 0.3, color="blue") +
facet_grid(CONTROL ~ income_group) +
geom_smooth(color="red") +
ylim(0, 50000)
p

Adding titles, axis labels, and legend labels
Good labels are critical for making your plots accessible to a wider audience. It’s important to ensure axis and legend labels display the full variable name (or a logical abbreviaition), but this does not always happen by default.
To add/alter these annotations we simply add a new layer using the labs function.
Adding a title
p <- p + labs(title = "Average Net Cost per Year at U.S. Colleges")
p

Adding a subtitle
p <- p + labs(subtitle = "By income quintile")
p

Changing the axis labels
p + labs(x = "Admissions rate, %",
y = "Net cost per year, $'000")

Changing the legend labels
scorecard %>%
ggplot(aes(x=ADM_RATE, y=net_cost, color=ADM_RATE)) +
geom_point(alpha = 0.3) +
facet_grid(CONTROL ~ income_group) +
geom_smooth(color="darkorange") +
ylim(0, 50000) +
labs(title = "Average Net Cost per Year at U.S. Colleges",
subtitle = "By income quintile",
x = "Admissions rate, %",
y = "Net cost per year, $'000",
color = "Admissions\nRate")

Ordering factors
Sometimes we need to order the levels of a factor to make a plot meaningful.
To examine this, let’s look at a new data set which contains informatio on the 10 most popular baby names in 2014.
babynames <- read_csv("https://github.com/cmsc205/data/raw/master/top10babynames2014.csv")
babynames %>%
ggplot(aes(x = name, y = n, fill = sex)) +
geom_bar(stat = "identity")

To do this with respect to another variable we can use the reorder function.
babynames$name <- reorder(babynames$name, FUN = identity, babynames$n)
p2 <- babynames %>%
ggplot(aes(x = name, y = n, fill = sex)) +
geom_bar(stat = "identity") +
labs(title = "Top 10 Baby Names of 2014", x = NULL, y = "Count") +
coord_flip()
Choosing color palettes
ggplot2 does not choose the nicest looking palettes, and the palettes are typically not colorblind friendly. Luckily, it’s quite easy to change the color palettes you use.
Manual adjustments
To manually adjust the colors we can use the functions scale_color_manual or scale_fill_manual
p2 + scale_fill_manual(values = c("deeppink", "steelblue"))

Using RColorBrewer
You can let the RColorBrewer package choose the colors for you using the color_scale_brewer and fill_scale_brewer functions.
p2 + scale_fill_brewer(palette = "Dark2")

You can see all of the possible palettes in the package by running
RColorBrewer::display.brewer.all()

Using viridis
If you install the viridis package (this might not be on the server), then you can use the scale_color_viridis and scale_fill_viridis functions.
library(viridis)
p2 + scale_fill_viridis(discrete = TRUE)

A colorblind friendly palette
The ggthemes package contains a colorblind-friendly palette, which can be adopted using the scale_color_colorblind and scale_fill_colorblind functions.
library(ggthemes)
p2 + scale_fill_colorblind()

Choosing themes
By default ggplot2 uses a grey background and guidlines on a plot; however, we don’t always want our plots to appear this way. To change this the appearance, we need to work with themes.
The ggthemes package offers many additional choices.
We can use an existing theme just like adding a layer.
p + theme_minimal()

p + theme_hc()

Customizing themes
Sometimes the ggthemes package won’t do exactly what you want so you will have to dig into ggplot2 a bit deeper and create your own theme.
See ?theme for a list of all of the components that you can modify.
babynames %>%
ggplot(aes(x = name, y = n)) +
geom_bar(stat = "identity") +
geom_text(aes(label = n), vjust=1.5, color = "white") +
theme(axis.title.x = element_blank(),
axis.title.y = element_blank(),
panel.background = element_blank(),
axis.ticks.x = element_blank(),
axis.ticks.y = element_blank(),
axis.text.y = element_blank(),
axis.text.x = element_text(vjust = -2))

LS0tCnRpdGxlOiAiQ3VzdG9taXppbmcgUGxvdHMiCm91dHB1dDogaHRtbF9ub3RlYm9vawotLS0KCldlIG5vdyBrbm93IGhvdyB0byBjcmVhdGUgbWFueSBwbG90IHR5cGVzIHVzaW5nIGBnZ3Bsb3QyYCwgYnV0IG9mdGVuIHlvdSB3YW50IHRvIGN1c3RvbWl6ZSB5b3VyIHBsb3RzLiBUb2RheSwgd2UnbGwgZGlzY3VzcyBjb21tb24gdG9vbHMgZm9yIGN1c3RvbWl6aW5nIG91ciBwbG90cy4KClRvIGJlZ2luLCBtYWtlIHN1cmUgdGhhdCB5b3UgaGF2ZSB0aGUgYHRpZHl2ZXJzZWAgbG9hZGVkLgoKYGBge3IgbWVzc2FnZT1GQUxTRX0KbGlicmFyeSh0aWR5dmVyc2UpCmBgYAoKQWxzbywgbGV0J3Mgc3RhcnQgd2l0aCBvdXIgcGxvdCBmcm9tIHRoZSBleGVyY2lzZQoKYGBge3J9CnNjb3JlY2FyZCA8LSByZWFkX2NzdigiaHR0cHM6Ly9naXRodWIuY29tL2Ntc2MyMDUvZGF0YS9yYXcvbWFzdGVyL1Njb3JlY2FyZFNtYWxsTmFycm93LmNzdiIpCmBgYAoKYGBge3J9CnAgPC0gCiAgc2NvcmVjYXJkICU+JQogIGdncGxvdChhZXMoeD1BRE1fUkFURSwgeT1uZXRfY29zdCkpICsgCiAgZ2VvbV9wb2ludChhbHBoYSA9IDAuMywgY29sb3I9ImJsdWUiKSArIAogIGZhY2V0X2dyaWQoQ09OVFJPTCB+IGluY29tZV9ncm91cCkgKwogIGdlb21fc21vb3RoKGNvbG9yPSJyZWQiKSArIAogIHlsaW0oMCwgNTAwMDApCnAKYGBgCgoKIyBBZGRpbmcgdGl0bGVzLCBheGlzIGxhYmVscywgYW5kIGxlZ2VuZCBsYWJlbHMKCgpHb29kIGxhYmVscyBhcmUgY3JpdGljYWwgZm9yIG1ha2luZyB5b3VyIHBsb3RzIGFjY2Vzc2libGUgdG8gYSB3aWRlciBhdWRpZW5jZS4gSXQncyBpbXBvcnRhbnQgdG8gZW5zdXJlIGF4aXMgYW5kIGxlZ2VuZCBsYWJlbHMgZGlzcGxheSB0aGUgZnVsbCB2YXJpYWJsZSBuYW1lIChvciBhIGxvZ2ljYWwgYWJicmV2aWFpdGlvbiksIGJ1dCB0aGlzIGRvZXMgbm90IGFsd2F5cyBoYXBwZW4gYnkgZGVmYXVsdC4gCgpUbyBhZGQvYWx0ZXIgdGhlc2UgYW5ub3RhdGlvbnMgd2Ugc2ltcGx5IGFkZCBhIG5ldyBsYXllciB1c2luZyB0aGUgYGxhYnNgIGZ1bmN0aW9uLgoKCiMjIyMgQWRkaW5nIGEgdGl0bGUKCmBgYHtyfQpwIDwtIHAgKyBsYWJzKHRpdGxlID0gIkF2ZXJhZ2UgTmV0IENvc3QgcGVyIFllYXIgYXQgVS5TLiBDb2xsZWdlcyIpCnAKYGBgCgojIyMjIEFkZGluZyBhIHN1YnRpdGxlCgpgYGB7cn0KcCA8LSBwICsgbGFicyhzdWJ0aXRsZSA9ICJCeSBpbmNvbWUgcXVpbnRpbGUiKQpwCmBgYAoKIyMjIyBDaGFuZ2luZyB0aGUgYXhpcyBsYWJlbHMKCmBgYHtyfQpwICsgbGFicyh4ID0gIkFkbWlzc2lvbnMgcmF0ZSwgJSIsIAogICAgICAgICB5ID0gIk5ldCBjb3N0IHBlciB5ZWFyLCAkJzAwMCIpCmBgYAoKCiMjIyMgQ2hhbmdpbmcgdGhlIGxlZ2VuZCBsYWJlbHMKCmBgYHtyfQpzY29yZWNhcmQgJT4lCiAgZ2dwbG90KGFlcyh4PUFETV9SQVRFLCB5PW5ldF9jb3N0LCBjb2xvcj1BRE1fUkFURSkpICsgCiAgZ2VvbV9wb2ludChhbHBoYSA9IDAuMykgKyAKICBmYWNldF9ncmlkKENPTlRST0wgfiBpbmNvbWVfZ3JvdXApICsKICBnZW9tX3Ntb290aChjb2xvcj0iZGFya29yYW5nZSIpICsgCiAgeWxpbSgwLCA1MDAwMCkgKwogIGxhYnModGl0bGUgPSAiQXZlcmFnZSBOZXQgQ29zdCBwZXIgWWVhciBhdCBVLlMuIENvbGxlZ2VzIiwKICAgICAgIHN1YnRpdGxlID0gIkJ5IGluY29tZSBxdWludGlsZSIsCiAgICAgICB4ID0gIkFkbWlzc2lvbnMgcmF0ZSwgJSIsIAogICAgICAgeSA9ICJOZXQgY29zdCBwZXIgeWVhciwgJCcwMDAiLAogICAgICAgY29sb3IgPSAiQWRtaXNzaW9uc1xuUmF0ZSIpCmBgYAoKCiMgT3JkZXJpbmcgZmFjdG9ycwoKU29tZXRpbWVzIHdlIG5lZWQgdG8gb3JkZXIgdGhlIGxldmVscyBvZiBhIGZhY3RvciB0byBtYWtlIGEgcGxvdCBtZWFuaW5nZnVsLgoKVG8gZXhhbWluZSB0aGlzLCBsZXQncyBsb29rIGF0IGEgbmV3IGRhdGEgc2V0IHdoaWNoIGNvbnRhaW5zIGluZm9ybWF0aW8gb24gdGhlIDEwIG1vc3QgcG9wdWxhciBiYWJ5IG5hbWVzIGluIDIwMTQuCgpgYGB7cn0KYmFieW5hbWVzIDwtIHJlYWRfY3N2KCJodHRwczovL2dpdGh1Yi5jb20vY21zYzIwNS9kYXRhL3Jhdy9tYXN0ZXIvdG9wMTBiYWJ5bmFtZXMyMDE0LmNzdiIpCmBgYAoKYGBge3J9CmJhYnluYW1lcyAlPiUKICBnZ3Bsb3QoYWVzKHggPSBuYW1lLCB5ID0gbiwgZmlsbCA9IHNleCkpICsKICBnZW9tX2JhcihzdGF0ID0gImlkZW50aXR5IikKYGBgCgoKClRvIGRvIHRoaXMgd2l0aCByZXNwZWN0IHRvIGFub3RoZXIgdmFyaWFibGUgd2UgY2FuIHVzZSB0aGUgYHJlb3JkZXJgIGZ1bmN0aW9uLiAKCmBgYHtyfQpiYWJ5bmFtZXMkbmFtZSA8LSByZW9yZGVyKGJhYnluYW1lcyRuYW1lLCBGVU4gPSBpZGVudGl0eSwgYmFieW5hbWVzJG4pCgpwMiA8LSBiYWJ5bmFtZXMgJT4lCiAgZ2dwbG90KGFlcyh4ID0gbmFtZSwgeSA9IG4sIGZpbGwgPSBzZXgpKSArCiAgZ2VvbV9iYXIoc3RhdCA9ICJpZGVudGl0eSIpICsgCiAgbGFicyh0aXRsZSA9ICJUb3AgMTAgQmFieSBOYW1lcyBvZiAyMDE0IiwgeCA9IE5VTEwsIHkgPSAiQ291bnQiKSArCiAgY29vcmRfZmxpcCgpCnAyCmBgYAoKCgojIENob29zaW5nIGNvbG9yIHBhbGV0dGVzCgpgZ2dwbG90MmAgZG9lcyBub3QgY2hvb3NlIHRoZSBuaWNlc3QgbG9va2luZyBwYWxldHRlcywgYW5kIHRoZSBwYWxldHRlcyBhcmUgdHlwaWNhbGx5IG5vdCBjb2xvcmJsaW5kIGZyaWVuZGx5LiBMdWNraWx5LCBpdCdzIHF1aXRlIGVhc3kgdG8gY2hhbmdlIHRoZSBjb2xvciBwYWxldHRlcyB5b3UgdXNlLgoKIyMjIyBNYW51YWwgYWRqdXN0bWVudHMKClRvIG1hbnVhbGx5IGFkanVzdCB0aGUgY29sb3JzIHdlIGNhbiB1c2UgdGhlIGZ1bmN0aW9ucyBgc2NhbGVfY29sb3JfbWFudWFsYCBvciBgc2NhbGVfZmlsbF9tYW51YWxgCgpgYGB7cn0KcDIgKyBzY2FsZV9maWxsX21hbnVhbCh2YWx1ZXMgPSBjKCJkZWVwcGluayIsICJzdGVlbGJsdWUiKSkKYGBgCgoKIyMjIyBVc2luZyBSQ29sb3JCcmV3ZXIKCllvdSBjYW4gbGV0IHRoZSBSQ29sb3JCcmV3ZXIgcGFja2FnZSBjaG9vc2UgdGhlIGNvbG9ycyBmb3IgeW91IHVzaW5nIHRoZSBgY29sb3Jfc2NhbGVfYnJld2VyYCBhbmQgYGZpbGxfc2NhbGVfYnJld2VyYCBmdW5jdGlvbnMuIAoKYGBge3J9CnAyICsgc2NhbGVfZmlsbF9icmV3ZXIocGFsZXR0ZSA9ICJEYXJrMiIpCmBgYAoKCllvdSBjYW4gc2VlIGFsbCBvZiB0aGUgcG9zc2libGUgcGFsZXR0ZXMgaW4gdGhlIHBhY2thZ2UgYnkgcnVubmluZyAKCmBgYHtyfQpSQ29sb3JCcmV3ZXI6OmRpc3BsYXkuYnJld2VyLmFsbCgpCmBgYAoKCiMjIyMgVXNpbmcgdmlyaWRpcwoKSWYgeW91IGluc3RhbGwgdGhlIHZpcmlkaXMgcGFja2FnZSAodGhpcyBtaWdodCBub3QgYmUgb24gdGhlIHNlcnZlciksIHRoZW4geW91IGNhbiB1c2UgdGhlIGBzY2FsZV9jb2xvcl92aXJpZGlzYCBhbmQgYHNjYWxlX2ZpbGxfdmlyaWRpc2AgZnVuY3Rpb25zLgoKYGBge3J9CmxpYnJhcnkodmlyaWRpcykKcDIgKyBzY2FsZV9maWxsX3ZpcmlkaXMoZGlzY3JldGUgPSBUUlVFKQpgYGAKCiMjIyMgQSBjb2xvcmJsaW5kIGZyaWVuZGx5IHBhbGV0dGUKClRoZSBgZ2d0aGVtZXNgIHBhY2thZ2UgY29udGFpbnMgYSBjb2xvcmJsaW5kLWZyaWVuZGx5IHBhbGV0dGUsIHdoaWNoIGNhbiBiZSBhZG9wdGVkIHVzaW5nIHRoZSBgc2NhbGVfY29sb3JfY29sb3JibGluZGAgYW5kIGBzY2FsZV9maWxsX2NvbG9yYmxpbmRgIGZ1bmN0aW9ucy4KCgpgYGB7cn0KbGlicmFyeShnZ3RoZW1lcykKcDIgKyBzY2FsZV9maWxsX2NvbG9yYmxpbmQoKQpgYGAKCgoKCiMgQ2hvb3NpbmcgdGhlbWVzCgpCeSBkZWZhdWx0IGBnZ3Bsb3QyYCB1c2VzIGEgZ3JleSBiYWNrZ3JvdW5kIGFuZCBndWlkbGluZXMgb24gYSBwbG90OyBob3dldmVyLCB3ZSBkb24ndCBhbHdheXMgd2FudCBvdXIgcGxvdHMgdG8gYXBwZWFyIHRoaXMgd2F5LiBUbyBjaGFuZ2UgdGhpcyB0aGUgYXBwZWFyYW5jZSwgd2UgbmVlZCB0byB3b3JrIHdpdGggdGhlbWVzLgoKVGhlIGBnZ3RoZW1lc2AgcGFja2FnZSBvZmZlcnMgbWFueSBhZGRpdGlvbmFsIFtjaG9pY2VzXShodHRwczovL2dpdGh1Yi5jb20vanJub2xkL2dndGhlbWVzKS4gCgpXZSBjYW4gdXNlIGFuIGV4aXN0aW5nIHRoZW1lIGp1c3QgbGlrZSBhZGRpbmcgYSBsYXllci4KCgpgYGB7cn0KcCArIHRoZW1lX21pbmltYWwoKQpgYGAKCgpgYGB7cn0KcCArIHRoZW1lX2hjKCkKYGBgCgoKIyBDdXN0b21pemluZyB0aGVtZXMKClNvbWV0aW1lcyB0aGUgYGdndGhlbWVzYCBwYWNrYWdlIHdvbid0IGRvIGV4YWN0bHkgd2hhdCB5b3Ugd2FudCBzbyB5b3Ugd2lsbCBoYXZlIHRvIGRpZyBpbnRvIGBnZ3Bsb3QyYCBhIGJpdCBkZWVwZXIgYW5kIGNyZWF0ZSB5b3VyIG93biB0aGVtZS4KClNlZSBgP3RoZW1lYCBmb3IgYSBsaXN0IG9mIGFsbCBvZiB0aGUgY29tcG9uZW50cyB0aGF0IHlvdSBjYW4gbW9kaWZ5LgoKCmBgYHtyfQpiYWJ5bmFtZXMgJT4lCiAgZ2dwbG90KGFlcyh4ID0gbmFtZSwgeSA9IG4pKSArCiAgZ2VvbV9iYXIoc3RhdCA9ICJpZGVudGl0eSIpICsgCiAgZ2VvbV90ZXh0KGFlcyhsYWJlbCA9IG4pLCB2anVzdD0xLjUsIGNvbG9yID0gIndoaXRlIikgKwogIHRoZW1lKGF4aXMudGl0bGUueCA9IGVsZW1lbnRfYmxhbmsoKSwKICAgICAgICBheGlzLnRpdGxlLnkgPSBlbGVtZW50X2JsYW5rKCksCiAgICAgICAgcGFuZWwuYmFja2dyb3VuZCA9IGVsZW1lbnRfYmxhbmsoKSwKICAgICAgICBheGlzLnRpY2tzLnggPSBlbGVtZW50X2JsYW5rKCksCiAgICAgICAgYXhpcy50aWNrcy55ID0gZWxlbWVudF9ibGFuaygpLAogICAgICAgIGF4aXMudGV4dC55ID0gZWxlbWVudF9ibGFuaygpKQpgYGAKCg==